package com.xingxue.logistics.service;

import com.xingxue.logistics.common.dto.SysUser;
import com.xingxue.logistics.common.vo.RoleCheck;
import com.xingxue.logistics.common.vo.TreeNode;
import com.xingxue.logistics.common.dto.SysMenu;
import com.xingxue.logistics.common.dto.SysMenuExample;
import com.xingxue.logistics.common.dto.SysRole;
import com.xingxue.logistics.common.dto.SysRoleExample;
import com.xingxue.logistics.common.dto.SysRoleMenu;
import com.xingxue.logistics.common.dto.SysRoleMenuExample;
import com.xingxue.logistics.common.dto.SysRoleUser;
import com.xingxue.logistics.common.dto.SysRoleUserExample;
import com.xingxue.logistics.dao.mapper.SysMenuMapper;
import com.xingxue.logistics.dao.mapper.SysRoleMapper;
import com.xingxue.logistics.dao.mapper.SysRoleMenuMapper;
import com.xingxue.logistics.dao.mapper.SysRoleUserMapper;
import com.xingxue.logistics.dao.mapper.SysUserMapper;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author Kris at 2018/10/9 17:16
 */
@Service
public class LimitServiceImpl implements LimitService {

    @Autowired
    SysRoleMenuMapper roleMenuMapper;
    @Autowired
    SysRoleUserMapper roleUserMapper;
    @Autowired
    SysMenuMapper menuMapper;
    @Autowired
    SysRoleMapper roleMapper;
    @Autowired
    SysUserMapper userMapper;

    @Autowired
    MenuService menuService;
    @Autowired
    RoleService roleService;


    @Override
    public List<Integer> loadMenuIdByRoleId(Integer roleId) {
        SysRoleMenuExample example = new SysRoleMenuExample();
        example.createCriteria().andRoleIdEqualTo(roleId);
        List<SysRoleMenu> sysRoleMenus = roleMenuMapper.selectByExample(example);

        List<Integer> menuIds = sysRoleMenus.stream().map(sysRoleMenu -> {
            return sysRoleMenu.getMenuId();
        }).collect(Collectors.toList());
        return menuIds;
    }

    @Override
    public List<Integer> loadMenuIdByRoleId(List<Integer> roleIds) {
        SysRoleMenuExample example = new SysRoleMenuExample();
        example.createCriteria().andRoleIdIn(roleIds);
        List<SysRoleMenu> sysRoleMenus = roleMenuMapper.selectByExample(example);

        List<Integer> menuIds = sysRoleMenus.stream().map(sysRoleMenu -> {
            return sysRoleMenu.getMenuId();
        }).collect(Collectors.toList());
        return menuIds;
    }

    @Override
    public List<SysMenu> loadMenuByIds(List<Integer> menuIds) {
        //2.根据menuId查询所有的菜单
        SysMenuExample menuExample = new SysMenuExample();
        menuExample.setOrderByClause("id asc");
        menuExample.createCriteria().andIdIn(menuIds);
        return menuMapper.selectByExample(menuExample);
    }


    @Override
    public List<Integer> loadRoleIdByUserId(Integer userId) {
        SysRoleUserExample example = new SysRoleUserExample();
        example.createCriteria().andUserIdEqualTo(userId);
        List<SysRoleUser> sysRoleUsers = roleUserMapper.selectByExample(example);
        List<Integer> roleIds = sysRoleUsers.stream().map(sysRoleUser -> {
            return sysRoleUser.getRoleId();
        }).collect(Collectors.toList());
        return  roleIds;
    }

    @Override
    public List<SysRole> loadRoleByIds(List<Integer> roleIdList) {
        SysRoleExample example = new SysRoleExample();
        example.setOrderByClause("id asc");
        example.createCriteria().andIdIn(roleIdList);
        return roleMapper.selectByExample(example);
    }


    @Override
    public List<TreeNode> loadRoleMenuTree(Integer roleId) {
        //查询所有的菜单
        List<SysMenu> all = menuService.loadAll();
        //有权限的菜单ID
        List<Integer> checkedIds = this.loadMenuIdByRoleId(roleId);

        //将菜单转换为List<TreeNode>,并且设置是否选中
        List<TreeNode> treeNodes = new LinkedList<>();
        for(SysMenu menu:all){
            Boolean isLimit = false;
            if(checkedIds.contains(menu.getId())){
                isLimit = true;
            }
            TreeNode treeNode = new TreeNode(menu.getId(), menu.getParentId(), menu.getName(), menu.getUrl(),isLimit, null);
            treeNodes.add(treeNode);
        }
        return TreeNode.buildTree(treeNodes);
    }

    @Override
    public boolean saveRoleMenu(Integer roleId, List<Integer> menuIds, Boolean checked) {
        //先删除
        SysRoleMenuExample example = new SysRoleMenuExample();
        example.createCriteria().andRoleIdEqualTo(roleId).andMenuIdIn(menuIds);
        roleMenuMapper.deleteByExample(example);
        if(checked){
            for (Integer menuId: menuIds){
                SysRoleMenu roleMenu = new SysRoleMenu();
                roleMenu.setMenuId(menuId);
                roleMenu.setRoleId(roleId);
                roleMenuMapper.insert(roleMenu);
            }
        }
        return true;
    }

    @Override
    public List<RoleCheck> loadUserRoles(Integer userId) {
        List<SysRole> all = roleService.loadAll();
        List<Integer> checkedIds = this.loadRoleIdByUserId(userId);

        List<RoleCheck> result = new LinkedList<>();
        for(SysRole role:all){
            RoleCheck roleCheck = new RoleCheck(role);
            boolean checked = false;
            if(checkedIds.contains(roleCheck.getId())){
                checked = true;
            }
            roleCheck.setChecked(checked);
            result.add(roleCheck);
        }
        return result;
    }

    @Override
    public boolean saveUserRole(Integer roleId, Integer userId, Boolean checked) {
        //先删除
        SysRoleUserExample example = new SysRoleUserExample();
        example.createCriteria().andRoleIdEqualTo(roleId).andUserIdEqualTo(userId);
        roleUserMapper.deleteByExample(example);
        //再增加
        if(checked){
            SysRoleUser roleUser = new SysRoleUser();
            roleUser.setRoleId(roleId);
            roleUser.setUserId(userId);
            roleUserMapper.insert(roleUser);
        }
        return true;
    }


    @Override
    public List<SysUser> loadUserByRoleId(Integer roleId) {
        return userMapper.loadUserByRoleId(roleId);
    }
}
